﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using EmbeddedSharp.Core;
using ZedGraph;
using WeifenLuo.WinFormsUI.Docking;

namespace Zove.Desktop {
    public partial class PlottingForm : DockContent {

        private IUnaryParameterFunction[] ufList = null;

        private string title = string.Empty;

        private string xAxisName;

        private string yAxisName;

        private double from;

        private double to;

        private string var;

        public PlottingForm() {
            InitializeComponent();
        }

        public PlottingForm(
            string title, string xAxisName,
            string yAxisName, string var,
            double from, double to,
            params IUnaryParameterFunction[] functions) {
            this.title = title;
            this.xAxisName = xAxisName;
            this.yAxisName = yAxisName;
            this.from = from;
            this.to = to;
            this.ufList = functions;
            this.var = var;

            InitializeComponent();

        }


        private delegate void ShowGraphicsDelegate(object args);

        public void ShowGraphics(object args) {
            if (DesktopFormContext.Context.Main.InvokeRequired) {
                ShowGraphicsDelegate d
                    = new ShowGraphicsDelegate(ShowGraphics);
                this.Invoke(
                d, DesktopFormContext.Context.Main);
            } else {
                Form1 mainForm = args as Form1;
                this.MdiParent = mainForm;
                Show(mainForm.DockPanel);
            }
        }

        private void PlottingForm_Load(object sender, EventArgs e) {
            // Get a reference to the GraphPane instance in the ZedGraphControl
            GraphPane myPane = zg1.GraphPane;

            // Set the titles and axis labels
            myPane.Title.Text = "My Test Graph";
            myPane.XAxis.Title.Text = "X Value";
            myPane.YAxis.Title.Text = "My Y Axis";

            // Make up some data points from the Sine function
            PointPairList list = new PointPairList();
            for (double x = this.from; x < this.to; x=x+(this.to-this.from)/1000) {
                double y = this.ufList[0].Eval(x);

                list.Add(x, y);
            }

            // Generate a blue curve with circle symbols, and "My Curve 2" in the legend
            LineItem myCurve = myPane.AddCurve("My Curve", list, Color.Blue,
                                    SymbolType.None);
            // Fill the area under the curve with a white-red gradient at 45 degrees
            //myCurve.Line.Fill = new Fill(Color.White, Color.Red, 45F);
            // Make the symbols opaque by filling them with white
            //myCurve.Symbol.Fill = new Fill(Color.White);

            // Fill the axis background with a color gradient
            myPane.Chart.Fill = new Fill(Color.White, Color.LightGoldenrodYellow, 45F);

            // Fill the pane background with a color gradient
            myPane.Fill = new Fill(Color.White, Color.FromArgb(220, 220, 255), 45F);

            // Calculate the Axis Scale Ranges
            this.zg1.AxisChange();
        }

        /// <summary>
        /// On resize action, resize the ZedGraphControl to fill most of the Form, with a small
        /// margin around the outside
        /// </summary>
        private void Form1_Resize(object sender, EventArgs e) {
            SetSize();
        }

        private void SetSize() {
            zg1.Location = new Point(10, 10);
            // Leave a small margin around the outside of the control
            zg1.Size = new Size(this.ClientRectangle.Width - 20,
                    this.ClientRectangle.Height - 20);
        }

        /// <summary>
        /// Display customized tooltips when the mouse hovers over a point
        /// </summary>
        private string MyPointValueHandler(ZedGraphControl control, GraphPane pane,
                        CurveItem curve, int iPt) {
            // Get the PointPair that is under the mouse
            PointPair pt = curve[iPt];

            return curve.Label.Text + " is " + pt.Y.ToString("f2") + " units at " + pt.X.ToString("f1") + " days";
        }

        /// <summary>
        /// Customize the context menu by adding a new item to the end of the menu
        /// </summary>
        private void MyContextMenuBuilder(ZedGraphControl control, ContextMenuStrip menuStrip,
                        Point mousePt, ZedGraphControl.ContextMenuObjectState objState) {
            ToolStripMenuItem item = new ToolStripMenuItem();
            item.Name = "add-beta";
            item.Tag = "add-beta";
            item.Text = "Add a new Beta Point";
            item.Click += new System.EventHandler(AddBetaPoint);

            menuStrip.Items.Add(item);
            menuStrip.RenderMode = ToolStripRenderMode.System;
        }

        /// <summary>
        /// Handle the "Add New Beta Point" context menu item.  This finds the curve with
        /// the CurveItem.Label = "Beta", and adds a new point to it.
        /// </summary>
        private void AddBetaPoint(object sender, EventArgs args) {
            // Get a reference to the "Beta" curve IPointListEdit
            IPointListEdit ip = zg1.GraphPane.CurveList["Beta"].Points as IPointListEdit;
            if (ip != null) {
                double x = ip.Count * 5.0;
                double y = Math.Sin(ip.Count * Math.PI / 15.0) * 16.0 * 13.5;
                ip.Add(x, y);
                zg1.AxisChange();
                zg1.Refresh();
            }
        }

        private void zg1_Load(object sender, EventArgs e) {

        }
    }
}
